package dkbta.server.domain.analyzer;

import java.io.File;
import java.util.Hashtable;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;



import dkbta.server.domain.cu.CUStub;
import dkbta.server.util.exceptions.FailedToAnalyseException;
import dkbta.server.util.query.PlanPair;
import dkbta.server.util.query.Query;
import dkbta.util.Pair;
import static dkbta.util.Utils.getDocument;
import static dkbta.util.Utils.xmlToString;
import static dkbta.util.Utils.writeXMLFile;

/**
 * @author Arkady Mishiev
 *
 */

public class QueryAnalyser /*extends AbstractQueryAnalyzer */{

	private static Logger s_logger;
	private static int debug = 0;
	
	public QueryAnalyser(){
		s_logger = Logger.getLogger(QueryAnalyser.class);
	}

	//changes query
	public void analyse(Vector<String> cuStubs, Query query) throws FailedToAnalyseException {
		s_logger.info("Begin to analyse query");			
		try {
			Element element = getDocument(query.getXMLString());
			String xmlPlans = query.getXMLString();
			AbstractQueryAnalyzer planMaker = AnalyzerFactory.getPlanMaker("SimpleAnalyzer", element);
			//writeXMLFile(element, "test.xml");
			/*<stubId,<plan,result>>*/
			String xmlPlanUpd = updatedUnitIds(xmlPlans, cuStubs);
			Hashtable<String, PlanPair> plansMap = planMaker.makePlans(cuStubs, xmlPlanUpd);
			s_logger.info("Query analysed ok");
			query.setPlans(plansMap);
		} 
		catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new FailedToAnalyseException();			
		} 			
	}

	private String updatedUnitIds(String planStr, Vector<String> cuStubs) {
		try{
			DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
			builderFactory.setNamespaceAware(true);
			DocumentBuilder builder = builderFactory.newDocumentBuilder();  
			Document xmlDoc = builder.parse("Task.xml");						
			Element element = (Element)xmlDoc.getElementsByTagName("Units").item(0);
			element.getParentNode().removeChild(element);
			xmlDoc.normalize();
			Element allUnitsEl = xmlDoc.createElement("Units");
			for(int i = 0; i < cuStubs.size(); i++){
				Element unit = xmlDoc.createElement("Unit");
				unit.setAttribute("id", getStubId(cuStubs.get(i)));
				unit.setAttribute("ip", getStubIp(cuStubs.get(i)));
				unit.setAttribute("dataPort", "3010");
				unit.setAttribute("controlPort", "2010");																							
				allUnitsEl.appendChild(unit);
			}
			xmlDoc.getDocumentElement().appendChild(allUnitsEl);
			xmlDoc.normalize();
			//writeXMLFile(xmlDoc.getDocumentElement(),(debug++) + "-RemovedUnits.xml");
			String xmlStr = xmlToString(xmlDoc.getDocumentElement()); 
			return xmlStr;
		}
		catch(Exception e){
			e.printStackTrace();
			//throw new Exception();
			return null;
		}				
	}

	private String getStubIp(String stub) {
		String tmp = stub.substring(stub.indexOf("@") + 1);
		tmp = tmp.substring(0,tmp.indexOf(":"));
		return tmp;
	}

	private String getStubId(String stub) {
		String id = stub.substring(0,stub.indexOf("@"));
		return id;
	}

}
